package com.example.testdemo.pools;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;

import com.example.testdemo.TankGameActivity;
import com.example.testdemo.kinetic.sprite.tank.enemy.EnemyTank1;
import com.example.testdemo.manager.ResourcesManager;
import com.example.testdemo.manager.ScenesManager;
import com.example.testdemo.resources.CharacterResources;
import com.example.testdemo.scenes.stage.BaseStage;

public class TankPools {
	@SuppressWarnings("unused")
    private final String TAG = TankPools.class.getSimpleName();
	
	public static final int DEFAULT_TANKS = 5;
	private static int mWhichScene = -1;
	
	private static TankPools INSTANCE = null;
	
	public static TankPools getInstance(int whichScene) {
		if (INSTANCE == null) {
			mWhichScene = whichScene;
			INSTANCE = new TankPools();
		} else {
			if (mWhichScene != whichScene) {
				INSTANCE.free();
			}
		}
		return INSTANCE;
	}

	private BaseStage mOnScene = null;
	private CharacterResources mCharacterResources = null;

	private int mMaxTanks = 0;
	private int mLeftCounts = 0;
	private ArrayBlockingQueue<EnemyTank1> mTankQueue = null;

	private TankPools() {
		mMaxTanks = DEFAULT_TANKS;
		mOnScene = (BaseStage) ScenesManager.getInstance().getScene(
		        mWhichScene);
		mCharacterResources = (CharacterResources) ResourcesManager
		        .getInstance().getResources(
		                ResourcesManager.RESOURCES_CHARACTER);
	}

	public void setMaxTanks(int max) {
		mMaxTanks = max;
	}

	public void initTanks(TankGameActivity activity, final int limit) {
		mLeftCounts = limit;
		mTankQueue = new ArrayBlockingQueue<EnemyTank1>(mMaxTanks);
		if (ScenesManager.SCENE_STAGE_1 == mWhichScene) {
			for (int i = 0; i < mMaxTanks; i++) {
				EnemyTank1 tank = new EnemyTank1(mWhichScene, EnemyTank1.BASE_NAME
				        + i, 0, 0,
				        mCharacterResources.mTankEnemy1TextureRegion, activity);
				tank.setTag(mOnScene.getSpriteTag().ENEMY_TANK_START + i);
				mOnScene.attachChild(tank);

				hideTank(tank);
				mTankQueue.add(tank);
			}
		}
	}

	public List<EnemyTank1> pullOutTanks(int count) {
		if (mLeftCounts == 0) {
			return null;
		}
		if (mLeftCounts < count) {
			count = mLeftCounts;
		}

		List<EnemyTank1> pullOutList = new ArrayList<EnemyTank1>();
		for (int i = 0; i < mMaxTanks; i++) {
			EnemyTank1 tank = mTankQueue.poll(); // retrieve a tank from queue
			                                     // head
			mTankQueue.add(tank); // re-add tank to queue's tail

			if (!tank.isVisible()) {
				pullOutList.add(tank);
				showTank(tank);
			}

			if (pullOutList.size() == count) {
				break;
			}
		}

		mLeftCounts -= pullOutList.size();
		return pullOutList;
	}

	public boolean isTanksAllOut() {
		return mTankQueue.size() == 0;
	}

	private void hideTank(EnemyTank1 tank) {
		tank.setAutoFire(false);
		tank.setVisible(false);
	}

	private void showTank(EnemyTank1 tank) {
		tank.resetSpriteData();
		tank.setVisible(true);
		tank.animate(new long[] { 100, 100 }, 1, 2, true);
	}

	public void recyle(EnemyTank1 tank) {
		hideTank(tank);
	}

	public void free() {
		for (EnemyTank1 tank : mTankQueue) {
			tank.free();
		}
		mTankQueue.clear();
		INSTANCE = null;
	}

}
